package configx

import (
	"strings"

	"gitee.com/zhongguo168a/gocodes/datax"
	"gitee.com/zhongguo168a/gocodes/datax/dictx"
	"gitee.com/zhongguo168a/gocodes/datax/mapx"
	"gitee.com/zhongguo168a/gocodes/datax/schemax"
	"gitee.com/zhongguo168a/gocodes/datax/treex"
)

func NewConfigRepo() (obj *ConfigRepo) {
	obj = &ConfigRepo{}
	obj.ConfigDict = NewConfigDict()
	obj.OnSet(func(key string, value *ConfigTreeItem) {
		{
			dict := obj.DictBy分类(value.F分类)
			dict.Set(value.B编号, value)
		}
		{
			dict := obj.DictBy文件(value.W文件)
			dict.Set(value.B编号, value)
		}
		{
			dict := obj.DictBy类型(value.L类型)
			dict.Set(value.B编号, value)
		}
		{
			功能 := mapx.String(value.数据, "功能")
			if 功能 != "" {
				dict := obj.DictBy功能(功能)
				dict.Set(value.B编号, value)
			}
		}
	})

	obj.OnDelete(func(key string, value *ConfigTreeItem) {
		{
			dict := obj.DictBy分类(value.F分类)
			dict.Delete(value.B编号)
		}
		{
			dict := obj.DictBy文件(value.W文件)
			dict.Delete(value.B编号)
		}
		{
			dict := obj.DictBy类型(value.L类型)
			dict.Delete(value.B编号)
		}
		{
			功能 := mapx.String(value.数据, "功能")
			if 功能 != "" {
				dict := obj.DictBy功能(功能)
				dict.Delete(value.B编号)
			}
		}
	})
	obj.index_catalog = dictx.New[string, *ConfigDict]()
	obj.index_file = dictx.New[string, *ConfigDict]()
	obj.index_类型 = dictx.New[string, *ConfigDict]()
	obj.index_功能 = dictx.New[string, *ConfigDict]()
	return
}

type ConfigRepo struct {
	*ConfigDict

	index_file    *dictx.Dictionary[string, *ConfigDict]
	index_catalog *dictx.Dictionary[string, *ConfigDict]
	index_类型      *dictx.Dictionary[string, *ConfigDict]
	index_功能      *dictx.Dictionary[string, *ConfigDict]
	index_tree    *treex.TreeRoot
}

func (set *ConfigRepo) IndexTree() *treex.TreeRoot {
	return set.index_tree
}

func (set *ConfigRepo) DictBy文件(文件 string) *ConfigDict {
	dict, ok := set.index_file.Get(文件)
	if !ok {
		dict = NewConfigDict()
		set.index_file.Set(文件, dict)
	}
	return dict
}

func (set *ConfigRepo) DictBy分类(分类 string) *ConfigDict {
	dict, ok := set.index_catalog.Get(分类)
	if !ok {
		dict = NewConfigDict()
		set.index_catalog.Set(分类, dict)
	}
	return dict
}

func (set *ConfigRepo) DictBy类型(类型 string) *ConfigDict {
	dict, ok := set.index_类型.Get(类型)
	if !ok {
		dict = NewConfigDict()
		set.index_类型.Set(类型, dict)
	}
	return dict
}
func (set *ConfigRepo) DictBy功能(功能 string) *ConfigDict {
	dict, ok := set.index_功能.Get(功能)
	if !ok {
		dict = NewConfigDict()
		set.index_功能.Set(功能, dict)
	}
	return dict
}
func (set *ConfigRepo) Load(files map[string]datax.M) {
	dict := NewConfigDict()
	for _, fileBody := range files {
		for key, iconf := range fileBody {
			conf := iconf.(datax.M)
			obj := NewTreeItemByConf(key, conf)
			delete(conf, "_type")
			delete(conf, "_name")
			delete(conf, "_namespace")
			delete(conf, "_catalog")
			delete(conf, "_parent")
			delete(conf, "_prefix")
			delete(conf, "_suffix")
			delete(conf, "_editor")
			delete(conf, "_export")
			delete(conf, "_default")
			delete(conf, "_file")
			decl := obj.GetSchema()
			if decl != nil {
				result, err := schemax.JustifyObject(conf, decl)
				if err != nil {
					panic(err)
				}
				obj.原始数据 = result
			} else {
				obj.原始数据 = conf
			}

			dict.Set(obj.B编号, obj)
		}
	}
	root := resetIndexTree(dict)

	// 初始化最终数据
	root.Walk(func(node *treex.TreeNode) bool {
		if node.Data == nil {
			return true
		}
		node配置 := node.Data.(*ConfigTreeItem)

		if node配置 == nil {
			return true
		}
		data := datax.M{}
		node配置.数据 = data

		decl := node配置.GetSchema()
		if decl != nil {
			_ = schemax.InitObj(data, decl)
		}

		if node.Parent != nil {
			parent := node.Parent.(*treex.TreeNode)
			if parent.Data != nil {
				parent配置 := parent.Data.(*ConfigTreeItem)
				mapx.Copy(parent配置.数据, data)
				if node配置.M命令空间 == "" {
					node配置.M命令空间 = parent配置.M命令空间
				}
				if node配置.L类型 == "" {
					node配置.L类型 = parent配置.L类型
				}
				if node配置.W文件 == "" {
					node配置.W文件 = parent配置.W文件
				}
				if node配置.F分类 == "" {
					node配置.F分类 = parent配置.F分类
				}
			}
		}
		mapx.Copy(node配置.原始数据, data)
		set.Set(node配置.B编号, node配置)
		return true
	})

	set.ResetIndexTree()
}

func (set *ConfigRepo) DictBy目录(目录 string) (result *ConfigDict) {
	result = NewConfigDict()
	for _, val := range set.Items() {
		if strings.Contains(val.W文件, 目录) {
			result.Set(val.B编号, val)
		}
	}
	return
}

// 重置并返回index_tree
func (set *ConfigRepo) ResetIndexTree() *treex.TreeRoot {
	var list []*treex.TreeListItem
	list = append(list, &treex.TreeListItem{
		Id: "/",
	})

	items := set.Items()
	for i := 0; i < len(items); i++ {
		item := items[i]
		if item.F父编号 != "" {
			list = append(list, &treex.TreeListItem{
				Id: item.B编号, Parent: item.F父编号, Data: item,
			})
		} else {
			list = append(list, &treex.TreeListItem{
				Id: item.B编号, Parent: "/", Data: item,
			})
		}
	}
	set.index_tree = resetIndexTree(set.ConfigDict)
	return set.index_tree
}
